package com.demo.zhou.sniper.util.tool;


import com.demo.zhou.sniper.module.MyValue;
import com.demo.zhou.sniper.module.Primitive;

import java.util.ArrayList;
import java.util.List;

/**
 * 查找颜色的工具类
 * 方案号取值与方向进行查表获得颜色
 * Created by zhou on 2017/3/16.
 */

public class Lookup {
    // 表，用于查找颜色用
    private List<Boolean> fangxList;

    public Lookup(List<Boolean> fangxList) {
        this.fangxList = fangxList;
    }

    /**
     * 计算目标颜色
     *
     * @param volue 通过方案号运行得到的值
     * @param fangX 传入当前方向，ture为横向，false为纵向
     * @return 目标色
     */
    public boolean lookupColor(int volue, boolean fangX) {
        if (fangX) {
            if (fangxList.get(volue - 1) == true) {
                return true;
            } else {
                return false;
            }
        } else {
            if (fangxList.get(volue - 1) == true) {
                return false;
            } else {
                return true;
            }
        }

    }

    /**
     * @param sColor 原始数实际颜色
     * @param mColor 目标色
     * @return
     */
    public boolean lookupDuicuo(Boolean sColor, Boolean mColor) {
        if (sColor.equals(mColor)) {
            return true;
        } else {
            return false;
        }

    }

    /**
     * 计算方向与换项处理
     * 传入对错表，传入方向表，第一次默认为对
     * 先检查当前对错，若对，检查是否为规律性变化，若不是规律性变化，则将当前的方向返回，若是，则换向
     * 若错，回查 判断是否为第一次出错，若是第一次出错~~~~~
     * 不是第一次出错，得到当次出错加前后两处对的方向，若前面继续错，则得到前面错的4次进行对比
     *
     */
    /**
     * @param v_list 结果集列表
     * @param p_list 原始数列表
     * @param fangAn 方案号
     * @param xian   当前运行的线
     * @param mXian  线的总数
     * @return 运算得到的目标色和方向的结果集
     */
    public List<MyValue> lockupVolue(List<MyValue> v_list, List<Primitive> p_list, String fangAn, int xian, int mXian) {
        List<MyValue> values = new ArrayList();
        values.addAll(v_list);
        //根据原始数和方案号获得的值
        int vfangAn = FangAnTool.p_Result(p_list, fangAn, xian, mXian);
        //取得当前输入的原始数
        Primitive primitive = p_list.get(p_list.size() - 1);
        if (p_list.size() - v_list.size() == 3) {
            MyValue myValue = values.get(v_list.size() - 1);
            if (lookupDuicuo(primitive.isColor(), myValue.ismColor())) {
                myValue.setDuicuo(true);
                myValue.setFormula(0);
                values.set(v_list.size() - 1, myValue);
                MyValue myValue1 = new MyValue();
                //对，判断是否规律性变化
                //进行规律性判断
                if (myValue.isLawLock()) {
                    //是规律性变化，换向
                    myValue1.setFangx(!myValue.isFangx());
                    myValue1.setmColor(lookupColor(vfangAn, !myValue.isFangx()));
                    myValue1.setFormula(0);
                    myValue1.setLawLock(true);
                    values.add(myValue1);
                } else if (glxbh(values)) {
                    //是规律性变化，换向
                    myValue1.setFangx(!myValue.isFangx());
                    myValue1.setmColor(lookupColor(vfangAn, !myValue.isFangx()));
                    myValue1.setFormula(0);
                    myValue1.setLawLock(true);
                    values.add(myValue1);
                } else {
                    //不是规律性变化
                    myValue1.setFangx(myValue.isFangx());
                    myValue1.setmColor(lookupColor(vfangAn, myValue.isFangx()));
                    myValue1.setFormula(0);
                    myValue1.setLawLock(false);
                    values.add(myValue1);
                }
            } else {
                /*错，是否是否在口诀状态，，不在口诀状态，回查
                 *在口诀状态，获取口诀，获得下一行的值
                 * 不在口诀状态，回查
                 */
                if (myValue.isFormula() < 1) {
                    //不在口诀内
                    //出错时回查
                    if (findError(values).length < 5) {
                        //首次出错
                        if (!myValue.isFangx()) {
                            myValue.setFormula(1);
                            myValue.setDuicuo(false);
                            myValue.setLawLock(false);
                            values.set(v_list.size() - 1, myValue);
                            MyValue myValue1 = new MyValue();
                            myValue1.setFangx(getFormulaFangx(1, 2));
                            myValue1.setFormula(1);
                            myValue1.setLawLock(false);
                            myValue1.setmColor(lookupColor(vfangAn, getFormulaFangx(1, 2)));
                            values.add(myValue1);
                        } else {
                            myValue.setFormula(2);
                            myValue.setDuicuo(false);
                            myValue.setLawLock(false);
                            values.set(v_list.size() - 1, myValue);
                            MyValue myValue1 = new MyValue();
                            myValue1.setFangx(getFormulaFangx(2, 2));
                            myValue1.setFormula(2);
                            myValue1.setLawLock(false);
                            myValue1.setmColor(lookupColor(vfangAn, getFormulaFangx(2, 2)));
                            values.add(myValue1);

                        }
                    } else {
                        //得到口诀的第一个字 re口诀
                        int re = getFormula(findError(values));
                        myValue.setDuicuo(false);
                        myValue.setFormula(re);
                        myValue.setLawLock(false);
                        values.set(v_list.size() - 1, myValue);
                        MyValue myValue1 = new MyValue();
                        myValue1.setFangx(getFormulaFangx(re, 2));
                        myValue1.setLawLock(false);
                        myValue1.setmColor(lookupColor(vfangAn, getFormulaFangx(re, 2)));
                        myValue1.setFormula(re);
                        values.add(myValue1);
                    }

                } else {
                    //得到在口诀的第几个字
                    MyValue qMyValue = values.get(v_list.size() - 2);
                    int formulanumb = getFormulanumb(myValue.isFormula(), qMyValue.isFangx(), myValue.isFangx());
                    if (formulanumb == 2) {
                        myValue.setDuicuo(false);
                        myValue.setLawLock(false);
                        values.set(v_list.size() - 1, myValue);
                        MyValue myValue1 = new MyValue();
                        myValue1.setFangx(getFormulaFangx(myValue.isFormula(), 3));
                        myValue1.setmColor(lookupColor(vfangAn, getFormulaFangx(myValue.isFormula(), 3)));
                        myValue1.setLawLock(false);
                        myValue1.setFormula(myValue.isFormula());
                        values.add(myValue1);
                    } else if (formulanumb == 3) {
                        //口诀的第三个字，修正
                        myValue.setDuicuo(false);
                        myValue.setLock(true);
                        myValue.setLawLock(false);
                        boolean b = myValue.isFangx();
                        myValue.setFangx(!b);
                        myValue.setFormula(0);
                        values.set(v_list.size() - 1, myValue);
                        MyValue myValue1 = new MyValue();
                        myValue1.setFangx(!b);
                        myValue1.setLawLock(false);
                        myValue1.setmColor(lookupColor(vfangAn, myValue.isFangx()));
                        myValue1.setFormula(0);
                        values.add(myValue1);
                    }
                }
            }

        } else {

        }

        return values;
    }


    /**
     * @param volue     首查时需要传入通过方案号运算出来的值
     * @param primitive 首查时需要传入的原始数
     *                  shou chang shi xyao chuan ru de se biao de wei zi
     * @return 首查获得的方向，true为横向，false为纵向
     */
    public boolean firstFangx(int volue, Primitive primitive) {
        boolean b;
        if (fangxList.get(volue - 1) == primitive.isColor()) {
            b = true;
        } else {
            b = false;
        }

        return b;

    }

    //回查
    private int[] findError(List<MyValue> volues) {
        int[] result = new int[3];
        if (volues.size() <= 2) {
            return result;
        } else {
            for (int i = volues.size() - 2; i > 2; i--) {
                MyValue myValue = volues.get(i);
                MyValue myValue1 = volues.get(i - 1);

                //出错并且不是修正状态
                if (!myValue.isDuicuo() && !myValue.isLock()) {
                    //一个错并且不是修正状态
                    if (myValue1.isDuicuo() && !myValue1.isLock()) {
                        //记录上下对与当前错的方向，返回
                        result = new int[5];
                        if (volues.get(volues.size() - 1).isFangx()) {
                            result[0] = 1;
                        } else {
                            result[0] = 0;
                        }
                        if (volues.get(volues.size() - 2).isFangx()) {
                            result[1] = 1;
                        } else {
                            result[1] = 0;
                        }
                        if (volues.get(i + 1).isFangx()) {
                            result[2] = 1;
                        } else {
                            result[2] = 0;
                        }
                        if (myValue.isFangx()) {
                            result[3] = 1;
                        } else {
                            result[3] = 0;
                        }
                        if (myValue1.isFangx() && !myValue1.isLock()) {
                            result[4] = 1;
                        } else if (!myValue1.isFangx() && !myValue1.isLock()) {
                            //纵向未修正
                            result[4] = 0;
                        } else if (myValue1.isFangx() && myValue1.isLock()) {
                            result[4] = 9;
                        } else if (!myValue1.isFangx() && myValue1.isLock()) {
                            //纵向修正
                            result[4] = 8;
                        }
                        return result;
                    } else if (!myValue1.isDuicuo() && myValue1.isLock()) {
                        result = new int[5];
                        result = new int[5];
                        if (volues.get(volues.size() - 1).isFangx()) {
                            result[0] = 1;
                        } else {
                            result[0] = 0;
                        }
                        if (volues.get(volues.size() - 2).isFangx()) {
                            result[1] = 1;
                        } else {
                            result[1] = 0;
                        }
                        if (volues.get(i + 1).isFangx()) {
                            result[2] = 1;
                        } else {
                            result[2] = 0;
                        }
                        if (myValue.isFangx()) {
                            result[3] = 1;
                        } else {
                            result[3] = 0;
                        }
                        if (myValue1.isFangx() && !myValue1.isLock()) {
                            result[4] = 1;
                        } else if (!myValue1.isFangx() && !myValue1.isLock()) {
                            //纵向未修正
                            result[4] = 0;
                        } else if (myValue1.isFangx() && myValue1.isLock()) {
                            result[4] = 9;
                        } else if (!myValue1.isFangx() && myValue1.isLock()) {
                            //纵向修正
                            result[4] = 8;
                        }
                        return result;
                    } else { //两个错
                        //记录上下对错与当前两个错的方向，并根据修正状态判断，返回
                        MyValue myValue2 = volues.get(i - 2);
                        result = new int[6];
                        if (volues.get(volues.size() - 1).isFangx()) {
                            result[0] = 1;
                        } else {
                            result[0] = 0;
                        }
                        if (volues.get(volues.size() - 2).isFangx()) {
                            result[1] = 1;
                        } else {
                            result[1] = 0;
                        }
                        if (volues.get(i + 1).isFangx() && !volues.get(i + 1).isLock()) {
                            //横向不修正
                            result[2] = 1;
                        } else if (!volues.get(i + 1).isFangx() && !volues.get(i + 1).isLock()) {
                            result[2] = 0;
                        }
                        if (myValue.isFangx()) {
                            result[3] = 1;
                        } else {
                            result[3] = 0;
                        }
                        if (myValue1.isFangx()) {
                            result[4] = 1;
                        } else {
                            result[4] = 0;
                        }
                        if (myValue2.isFangx() && !myValue2.isLock()) {
                            //横向并没有修正
                            result[5] = 1;
                        } else if (!myValue2.isFangx() && !myValue2.isLock()) {
                            //纵向并没有修正
                            result[5] = 0;
                        } else if (myValue2.isFangx() && myValue2.isLock()) {
                            //横向并修正
                            result[5] = 9;
                        } else if (!myValue2.isFangx() && myValue2.isLock()) {
                            //纵向带修正
                            result[5] = 8;
                        }
                        return result;
                    }
                } else if (!myValue.isDuicuo() && myValue.isLock()) {
                    //只有当后面两位都是错的时候才会出现强制换向
                    //记录后面两个错并且第三个对的方向  返回
                    MyValue myValue2 = volues.get(i - 2);
                    MyValue myValue3 = volues.get(i - 3);
                    result = new int[6];
                    if (volues.get(volues.size() - 1).isFangx()) {
                        result[0] = 1;//横为1，纵为2
                    } else {
                        result[0] = 0;
                    }
                    if (volues.get(volues.size() - 2).isFangx()) {
                        result[1] = 1;//横为1，纵为2
                    } else {
                        result[1] = 0;
                    }
                    if (myValue.isFangx()) {
                        result[2] = 9;
                        //横向并修正为9.纵向为8
                    } else if (!myValue.isFangx()) {
                        result[2] = 8;
                    }
                    if (myValue1.isFangx()) {
                        result[3] = 1;
                    } else {
                        result[3] = 0;
                    }
                    if (myValue2.isFangx()) {
                        result[4] = 1;
                    } else {
                        result[4] = 0;
                    }
                    if (myValue3.isFangx() && !myValue3.isLock()) {
                        //横向并没有修正
                        result[5] = 1;
                    } else if (!myValue3.isFangx() && !myValue3.isLock()) {
                        //纵向并没有修正
                        result[5] = 0;
                    } else if (myValue3.isFangx() && myValue3.isLock()) {
                        //横向并修正
                        result[5] = 9;
                    } else if (!myValue3.isFangx() && myValue3.isLock()) {
                        //纵向带修正
                        result[5] = 8;
                    }
                    return result;
                }

            }
            return result;
        }

    }

    /**
     * 规律性变化判断
     *
     * @param volues
     * @return
     */
    public boolean glxbh(List<MyValue> volues) {

        if (volues.size() < 4) {
            return false;
        } else if (volues.get(volues.size() - 2).isDuicuo()) {
            return false;
        } else if (volues.get(volues.size() - 2).isFangx() != volues.get(volues.size() - 1).isFangx()) {
            return false;
        } else {
            //方向横
            if (volues.get(volues.size() - 1).isFangx()) {
                boolean d1 = volues.get(volues.size() - 3).isDuicuo();
                boolean d2 = volues.get(volues.size() - 4).isDuicuo();
                boolean f1 = volues.get(volues.size() - 3).isFangx();
                boolean f2 = volues.get(volues.size() - 4).isFangx();
                if (d1 && !d2 && f1 && f2 && !volues.get(volues.size() - 4).isLock()) {
                    return true;
                } else if (!d1 && d2 && !f1 && !f2) {
                    return true;
                } else if (!d1 && !d2 && !f1 && !f2 && volues.get(volues.size() - 4).isLock()) {
                    return true;
                } else {
                    return false;
                }
            } else {
                boolean d1 = volues.get(volues.size() - 3).isDuicuo();
                boolean d2 = volues.get(volues.size() - 4).isDuicuo();
                boolean f1 = volues.get(volues.size() - 3).isFangx();
                boolean f2 = volues.get(volues.size() - 4).isFangx();
                if (d1 && !d2 && !f1 && !f2 && !volues.get(volues.size() - 4).isLock()) {
                    return true;
                } else if (!d1 && d2 && f1 && f2) {
                    return true;
                } else if (!d1 && !d2 && f1 && f2 && volues.get(volues.size() - 4).isLock()) {
                    return true;
                } else {
                    return false;
                }
            }
        }
    }

    private int getFormula(int[] result) {
        int formula = 0;
        if (result.length < 5 && result.length > 6) {
            return 0;
        } else {
            if (result[0] == 0) {
                //回查的第一项为纵
                if (result.length == 5) {
                    if (result[1] == 0 && result[2] == 0 && result[3] == 1 && result[4] == 1) {
                        formula = 1;
                    } else if (result[1] == 1 && result[2] == 0 && result[3] == 0 && result[4] == 0) {
                        formula = 1;
                    } else if (result[1] == 1 && result[2] == 1 && result[3] == 1 && result[4] == 1) {
                        formula = 1;
                    } else if (result[1] == 0 && result[2] == 0 && result[3] == 0 && result[4] == 0) {
                        formula = 3;
                    } else if (result[1] == 0 && result[2] == 0 && result[3] == 1 && result[4] == 9) {
                        formula = 3;
                    } else if (result[1] == 0 && result[2] == 0 && result[3] == 0 && result[4] == 8) {
                        formula = 3;
                    } else if (result[1] == 0 && result[2] == 0 && result[3] == 1 && result[4] == 0) {
                        formula = 3;
                    }
                } else {
                    if (result[1] == 1 && result[2] == 1 && result[3] == 1 && result[4] == 0 && result[5] == 0) {
                        formula = 1;
                    } else if (result[1] == 1 && result[2] == 1 && result[3] == 1 && result[4] == 0 && result[5] == 8) {
                        formula = 1;
                    } else if (result[1] == 1 && result[2] == 0 && result[3] == 0 && result[4] == 1 && result[5] == 1) {
                        formula = 1;
                    } else if (result[1] == 1 && result[2] == 0 && result[3] == 0 && result[4] == 1 && result[5] == 9) {
                        formula = 1;
                    } else if (result[1] == 0 && result[2] == 0 && result[3] == 1 && result[4] == 1 && result[5] == 1) {
                        formula = 1;
                    } else if (result[1] == 0 && result[2] == 8 && result[3] == 0 && result[4] == 0 && result[5] == 8) {
                        formula = 1;
                    } else if (result[1] == 0 && result[2] == 8 && result[3] == 1 && result[4] == 0 && result[5] == 1) {
                        formula = 1;
                    } else if (result[1] == 0 && result[2] == 0 && result[3] == 1 && result[4] == 1 && result[5] == 9) {
                        formula = 1;
                    } else if (result[1] == 0 && result[2] == 8 && result[3] == 0 && result[4] == 0 && result[5] == 0) {
                        formula = 1;
                    } else if (result[1] == 0 && result[2] == 8 && result[3] == 1 && result[4] == 0 && result[5] == 0) {
                        formula = 3;
                    } else if (result[1] == 0 && result[2] == 8 && result[3] == 1 && result[4] == 0 && result[5] == 8) {
                        formula = 3;
                    } else if (result[1] == 0 && result[2] == 0 && result[3] == 0 && result[4] == 1 && result[5] == 0) {
                        formula = 3;
                    }
                }
            } else if (result[0] == 1) {
                if (result.length == 5) {
                    if (result[1] == 1 && result[2] == 1 && result[3] == 0 && result[4] == 0) {
                        formula = 2;
                    } else if (result[1] == 0 && result[2] == 0 && result[3] == 0 && result[4] == 0) {
                        formula = 2;
                    } else if (result[1] == 0 && result[2] == 1 && result[3] == 1 && result[4] == 1) {
                        formula = 2;
                    } else if (result[1] == 1 && result[2] == 1 && result[3] == 1 && result[4] == 1) {
                        formula = 4;
                    } else if (result[1] == 1 && result[2] == 1 && result[3] == 0 && result[4] == 8) {
                        formula = 4;
                    } else if (result[1] == 1 && result[2] == 1 && result[3] == 1 && result[4] == 9) {
                        formula = 4;
                    } else if (result[1] == 1 && result[2] == 1 && result[3] == 0 && result[4] == 1) {
                        formula = 4;
                    } else {
                        formula = 1;
                    }
                } else {
                    if (result[1] == 0 && result[2] == 1 && result[3] == 1 && result[4] == 0 && result[5] == 0) {
                        formula = 2;
                    } else if (result[1] == 0 && result[2] == 1 && result[3] == 1 && result[4] == 0 && result[5] == 8) {
                        formula = 2;
                    } else if (result[1] == 0 && result[2] == 0 && result[3] == 0 && result[4] == 1 && result[5] == 1) {
                        formula = 2;
                    } else if (result[1] == 0 && result[2] == 0 && result[3] == 0 && result[4] == 1 && result[5] == 9) {
                        formula = 2;
                    } else if (result[1] == 1 && result[2] == 1 && result[3] == 0 && result[4] == 0 && result[5] == 0) {
                        formula = 2;
                    } else if (result[1] == 1 && result[2] == 9 && result[3] == 1 && result[4] == 1 && result[5] == 9) {
                        formula = 2;
                    } else if (result[1] == 1 && result[2] == 9 && result[3] == 0 && result[4] == 1 && result[5] == 0) {
                        formula = 2;
                    } else if (result[1] == 1 && result[2] == 9 && result[3] == 1 && result[4] == 1 && result[5] == 1) {
                        formula = 2;
                    } else if (result[1] == 1 && result[2] == 1 && result[3] == 0 && result[4] == 0 && result[5] == 8) {
                        formula = 2;
                    } else if (result[1] == 1 && result[2] == 9 && result[3] == 0 && result[4] == 1 && result[5] == 1) {
                        formula = 4;
                    } else if (result[1] == 1 && result[2] == 9 && result[3] == 0 && result[4] == 1 && result[5] == 9) {
                        formula = 4;
                    } else if (result[1] == 1 && result[2] == 1 && result[3] == 1 && result[4] == 0 && result[5] == 1) {
                        formula = 4;
                    } else {
                        formula = 1;
                    }
                }
            } else {
                return 0;
            }
        }
        return formula;
    }

    //得到下一个口诀的方向
    private boolean getFormulaFangx(int i, int s) {
        boolean b = false;
        if (i == 1) {
            boolean[] table = {false, true, true};
            b = table[s - 1];
        } else if (i == 2) {
            boolean[] table = {true, false, false};
            b = table[s - 1];
        } else if (i == 3) {
            boolean[] table = {false, false, true};
            b = table[s - 1];
        } else if (i == 4) {
            boolean[] table = {true, true, false};
            b = table[s - 1];
        }
        return b;
    }

    private int getFormulanumb(int koujTable, boolean qianFangx, boolean dangFangx) {
        int numb = 0;
        if (koujTable == 1) {
            if (qianFangx == dangFangx) {
                numb = 3;
            } else {
                numb = 2;
            }
        } else if (koujTable == 2) {
            if (qianFangx == dangFangx) {
                numb = 3;
            } else {
                numb = 2;
            }
        } else if (koujTable == 3) {
            if (qianFangx == dangFangx) {
                numb = 2;
            } else {
                numb = 3;
            }
        } else if (koujTable == 4) {
            if (qianFangx == dangFangx) {
                numb = 2;
            } else {
                numb = 3;
            }
        }

        return numb;
    }
}
